#include "bc_orthogonalFlowVelocity_velocity.hpp"
#include "meshTypes.hpp"
#include "field.hpp"
#include "boundaryPatch.hpp"
#include "sweFunctions.hpp"
#include "simulationTime.hpp"
#include "exceptions.hpp"
#include "geometry.hpp"

namespace hms {

// positive vBoundary => inflow
// negative vBoundary => outflow

#define CHEAD(RETURN_TYPE) \
template<typename MeshType> \
RETURN_TYPE OrthogonalFlowVelocity_velocity<MeshType>::


CHEAD() OrthogonalFlowVelocity_velocity(
	Field<MeshType>& f,
	const BoundaryPatch& p,
	scalar vBoundaryArg
) :
	BaseType(Type::orthogonalFlowVelocity_velocity, f, p)
{
	vBoundary(vBoundaryArg);
}

CHEAD(auto) vBoundary() const -> scalar {
	return m_vBoundary;
}

CHEAD(void) vBoundary(scalar vBoundaryArg){
	m_vBoundary = vBoundaryArg;

	Field<MeshType>& v { field() };
	const BoundaryPatch& p { patch() };
	/* the orthogonal flow velocity inside the ghost cells is set to
	 * vBoundary. A positive value means inflow, a negative one means outflow.
	 * This means, the normally "correct" orientation of normal vectors (outwards)
	 * is opposite of what's needed here */
	v.ghostValues(p) =
		(-m_vBoundary) * v.mesh().edges().outwardNormals(p).array();
	/* Simons (2019) states that v||ghost = v||inner, but that is not 
	 * implemented in hms, whose implementation is mimicked here */
}

#undef CHEAD

#define INSTANTIATE_FOR_ALL_MESHTYPES(MeshType) \
template class OrthogonalFlowVelocity_velocity<MeshType>;
#include "meshInstantiator.hpp"

}